home *** CD-ROM | disk | FTP | other *** search
/ Group 42-Sells Out! - The Information Archive / Group 42 Sells Out (Group 42) (1996).iso / crypto / rsan4exp.txt < prev    next >
Text File  |  1995-11-01  |  2KB  |  81 lines

  1. #!/usr/local/bin/perl -s-- #export-a-crypto-system sig, RSA in 4 lines PERL:
  2. #
  3. #         -d (decrypt) 
  4. #      or -e (encrypt)
  5. #
  6. # $k is exponent, $n is modulus; $k and $n in hex
  7. #
  8. # use of -s was contributed by Jeff Friedl, a cool perl hacker
  9. #
  10. # the $e-$d (grok that? awesome hack by Jeff also) checks for -d or -e:
  11. #
  12. #   when perl -s sets $x for -x so that means $d is set for -d, $e for -e
  13. #   if they are both set 1-1 = 0 so it fails if neither are set it fails
  14. #   and if either one is set we're ok!  This is to get around using | ,
  15. #   as | has higher precedence than & things group wrongly.
  16. #
  17. $e-$d&(($k,$n)=@ARGV)==2||die"$0 -d|-e key mod <in >out\n";
  18.  
  19. #
  20. # $v will be the digits of output per block, $w the digits of input per block.
  21. # If encrypting need to reduce $w so input is guaranteed to be less than
  22. # modulus; for decrypting reduce $v to match.
  23. #
  24. # blocks are based on modulus size in hex digits rounded up to nearest even 
  25. # length (~1&1+length$n) so that things will unpack properly
  26. #
  27. $v=$w=1+length$n&~1;
  28. $v-=$d*2:$w-=$e*2;
  29.  
  30. #
  31. # Make $_ be the exponent $k as a binary bit string
  32. #
  33. # Add a leading 0 to make length of $k be even so that it will fill
  34. # Bytes when packed as 2 digits per byte
  35. #
  36. $_=unpack('B*',pack('H*',1&length$k?"0$k":$k));
  37.  
  38. #
  39. # strip leading 0's from $_
  40. #
  41. s/^0+//;
  42.  
  43. #
  44. # Turn every 0 into "d*ln%", every 1 into "d*ln%lm*ln%".  These are dc codes
  45. # which construct an exponentiation algorithm for that exponent.
  46. # "d*ln%" is duplicate, square, load n, modulus; e.g. square the number
  47. # on the stack, mod n.  "d*ln%lm*ln%" does this then, load m, multiply,
  48. # load n, modulus; e.g. then multiply by m mod n.  This is the square and
  49. # multiply algorithm for modular exponentiation.
  50. #
  51. # (Kudos to Hal for shortened this one by 4 chars)
  52. #
  53.  
  54. s/1/0lM*ln%/g;
  55. s/0/d*ln%/g;
  56.  
  57. #
  58. # Encryption/decryption loop.  Read $w/2 bytes of data to $m.
  59. #
  60. while(read(STDIN,$m,$w/2)){
  61.  
  62. #
  63. # Turn data into equivalent hex digits in $m
  64. #
  65. $m=unpack("H$w",$m);
  66.  
  67. #
  68. # Run dc: 16 bit radix for input and output; $m into dc register "M";
  69. # $n into dc register "n"; execute $_, the exponentiation program above.
  70. # "\U...\E" forces upper case on the hex digits as dc requires.
  71. # Put the result in $e.
  72. #
  73. $a=`echo 16oOi\U$m SM$n\Esn1$_ p|dc`;
  74.  
  75. #
  76. # Pad the result with leading 0's to $v digits, pack to raw data and output.
  77. #
  78. print pack("H$v",'0'x($v+1-length$a).$a);
  79.  
  80. }
  81.